package com.ochnas.volunteersignup.ui;

import static com.ochnas.volunteersignup.ui.SharedConstants.SIMPLE_TIME_ZONE_FORMAT;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ochnas.volunteersignup.domain.Event;
import com.ochnas.volunteersignup.domain.FilledVolunteerRequisition;
import com.ochnas.volunteersignup.domain.Position;
import com.ochnas.volunteersignup.domain.TimeSlot;
import com.ochnas.volunteersignup.domain.User;
import com.ochnas.volunteersignup.service.EventService;
import com.ochnas.volunteersignup.service.UserService;
import com.ochnas.volunteersignup.service.VolunteerService;

public class ViewEventController {
	private ApplicationService applicationService;
	private VolunteerService volunteerService;
	private UserService userService;
	private EventService eventService;
	private User user;
	private Event event;
	private String currTimeZone;
	private List<Position> openPositions; // with and without time slots
	// mapOfTimeSlotVolunteers.key = positon.id
	private Map<Long, List<TimeSlot>> mapOfOpenTimeSlotsForPosition;
	private FilledVolunteerRequisition filledRequisition;
	

	public ViewEventController() {
		super();
		user = new User();
		event = new Event();
		openPositions = new ArrayList<Position>();
		mapOfOpenTimeSlotsForPosition = new HashMap<Long, List<TimeSlot>>();
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(System.currentTimeMillis());
		currTimeZone = "("+SIMPLE_TIME_ZONE_FORMAT.format(calendar.getTime()) + ")";
	}
	
	/**
	 * View the event detail : base information, volunteer position options and volunteer time slot options
	 * @return viewEvent.jsp
	 */
	public String viewEventDetail() {
		String eventId = applicationService.getRequestParameter("eventId");
		String userId = applicationService.getRequestParameter("userId");
		try {
			user = userService.findUserAccount(Long.parseLong(userId));
			event = eventService.findEvent(Long.parseLong(eventId));
			// this map contains open positions with and without time slots
			refreshEventDetail();
		} catch (NumberFormatException e) {
			applicationService.addErrorMessage(e.getMessage());
		}
		
		return "viewEventDetail";
	}	
	
	/**
	 * Performs refresh of event detail
	 */
	private void refreshEventDetail() {
		event = eventService.findEvent(event.getId());
		openPositions.clear();
		mapOfOpenTimeSlotsForPosition.clear();
		// this map contains open positions with and without time slots
		openPositions.addAll(volunteerService.findAllOpenPositionsByEvent(event.getId()));
		// this map contains positions to open time slots
		mapOfOpenTimeSlotsForPosition.putAll(volunteerService.findMapOfOpentTimeSlotsForPositionByEvent(event.getId()));

	}
	
	
	
	/**
	 * Assign volunteer to a position from viewEvent.jsp. If success, go to confirmSignUp page
	 * @return
	 */
	public String volunteerForPosition() {
		String positionId = applicationService.getRequestParameter("positionId");
		String userId = applicationService.getRequestParameter("userId");
		Position p = null;
		try {
			User user = userService.findUserAccount(Long.parseLong(userId));
			p = eventService.findPosition(Long.parseLong(positionId));
			filledRequisition = volunteerService.registerForEventByPosition(p, user);
			refreshEventDetail();
			
		} catch (NumberFormatException e) {
			applicationService.addErrorMessage("Could not volunteer. " + e.getMessage());
			return null;
		} catch (Exception e) {
			applicationService.addErrorMessage("viewEventDetailForm:summary" , e.getMessage());
			return null;
		}
		applicationService.addErrorMessage("confirmForm:summary", 
				"You've successfully volunteered for the position:" + 
				p.getName());
		return "confirmVolunteer";
	}
	
	/**
	 * Assign volunteer to a timeslot from viewEvent.jsp. If success, go to confirmVolunteer page
	 * @return
	 */
	public String volunteerForTimeSlot() {
		String timeSlotId = applicationService.getRequestParameter("timeSlotId");
		String userId = applicationService.getRequestParameter("userId");
		TimeSlot timeSlot = null;
		try {
			User volunteer = userService.findUserAccount(Long.parseLong(userId));
			timeSlot = eventService.findTimeSlot(Long.parseLong(timeSlotId));
			filledRequisition = volunteerService.registerForEventByTimeSlot(timeSlot, volunteer);
			refreshEventDetail();
		} catch (NumberFormatException e) {
			applicationService.addErrorMessage("Could not volunteer. " + e.getMessage());
			return null;
		}catch (Exception e) {
			applicationService.addErrorMessage("viewEventDetailForm:summary" , e.getMessage());
			return null;
		}
		applicationService.addErrorMessage("confirmForm:summary", 
				"You've successfully volunteered for the time slot: " + 
				timeSlot.getStartTime().toString() +" to "+
				timeSlot.getEndTime().toString());
		return "confirmVolunteer";
	}	
	
	public ApplicationService getApplicationService() {
		return applicationService;
	}
	public void setApplicationService(ApplicationService applicationService) {
		this.applicationService = applicationService;
	}
	public UserService getUserService() {
		return userService;
	}
	public void setUserService(UserService userService) {
		this.userService = userService;
	}
	public EventService getEventService() {
		return eventService;
	}
	public void setEventService(EventService eventService) {
		this.eventService = eventService;
	}
	public User getUser() {
		return user;
	}
	public void setUser(User user) {
		this.user = user;
	}
	public Event getEvent() {
		return event;
	}
	public void setEvent(Event event) {
		this.event = event;
	}

	public String getCurrTimeZone() {
		return currTimeZone;
	}

	public void setCurrTimeZone(String currTimeZone) {
		this.currTimeZone = currTimeZone;
	}

	public boolean isCreateMode() {
		return (event.getId() == null);
	}

	public VolunteerService getVolunteerService() {
		return volunteerService;
	}

	public void setVolunteerService(VolunteerService volunteerService) {
		this.volunteerService = volunteerService;
	}

	public List<Position> getOpenPositions() {
		return openPositions;
	}

	public void setOpenPositions(List<Position> openPositions) {
		this.openPositions = openPositions;
	}

	public FilledVolunteerRequisition getFilledRequisition() {
		return filledRequisition;
	}

	public void setFilledRequisition(FilledVolunteerRequisition filledRequisition) {
		this.filledRequisition = filledRequisition;
	}
	public boolean isAdministrator() {
		return (user.getId().equals(event.getCoordinator().getId()));
	}

	public Map<Long, List<TimeSlot>> getMapOfOpenTimeSlotsForPosition() {
		return mapOfOpenTimeSlotsForPosition;
	}

	public void setMapOfOpenTimeSlotsForPosition(
			Map<Long, List<TimeSlot>> mapOfOpenTimeSlotsForPosition) {
		this.mapOfOpenTimeSlotsForPosition = mapOfOpenTimeSlotsForPosition;
	}
	
}
